package com.xdxc.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xdxc.model.dto.ScoringResult;
import com.xdxc.model.form.ScoringRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.ollama.OllamaChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.ChatClient;
import org.springframework.stereotype.Service;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j
@Service
public class AIScoringService {

    private final ChatClient chatClient;
    private final ObjectMapper objectMapper;

    // 预编译正则表达式提升性能
    private static final Pattern JSON_PATTERN = Pattern.compile("\\{(?:[^{}]|\\{(?:[^{}]|\\{[^{}]*\\})*\\})*\\}");

    public AIScoringService(ChatClient chatClient, ObjectMapper objectMapper) {
        this.chatClient = chatClient;
        this.objectMapper = objectMapper;
    }

    public ScoringResult scoreAnswerWithReason(ScoringRequest request) {
        // 1. 构建符合评分标准的Prompt
        String prompt = buildScoringPrompt(request);

        try {
            // 2. 调用AI模型（带超时控制）
            String response = chatClient.call(prompt);
            log.debug("AI原始响应: {}", response);

            // 3. 清洗和解析响应
            JsonNode result = parseAndValidateResponse(response);

            // 4. 构建返回结果
            return buildScoringResult(result);

        } catch (Exception e) {
            return fallbackResult(request);
        }
    }

    private String buildScoringPrompt(ScoringRequest request) {
        return String.format("""
请严格按照以下规则执行评分任务：

### 评分标准（满分%.1f分）
1. **核心知识点**（60%%权重）：
   - 完全覆盖标准答案要点：6分
   - 部分覆盖（缺少1个要点）：3分
   - 完全错误或无关内容：0分

2. **语言表达**（30%%权重）：
   - 学术化严谨表达：3分
   - 基本达意但口语化：2分
   - 表述不清但可理解：1分
   - 完全混乱：0分

3. **逻辑连贯性**（10%%权重）：
   - 表述清晰连贯：1分
   - 逻辑自相矛盾：0分

### 输入数据
- 题目：%s
- 标准答案：%s
- 考生答案：%s

            ### 输出要求
            返回严格JSON格式：
            {
              "score": ,
              "knowledge_comment": "具体指出正确/错误要点",
              "language_comment": "语言评价",
              "logic_comment": "逻辑评价"
            }
            禁止包含```json等标记
            """,
                request.getMaxScore(),
                request.getQuestion(),
                request.getReference(),
                request.getStudentAnswer(),
                request.getMaxScore()
                );
    }

    private JsonNode parseAndValidateResponse(String response) throws Exception {
        // 1. 提取合法JSON部分
        Matcher matcher = JSON_PATTERN.matcher(response);
        if (!matcher.find()) {
            throw new IllegalArgumentException("未找到有效JSON响应");
        }
        String jsonStr = matcher.group();

        // 2. 基础清洗
        jsonStr = jsonStr.replaceAll("[“”]", "\"")
                .replaceAll("\\*\\*", "");

        // 3. 验证必需字段
        JsonNode node = objectMapper.readTree(jsonStr);
        if (!node.has("score") || !node.has("knowledge_comment")) {
            throw new IllegalArgumentException("缺少必需字段");
        }

        // 4. 验证分数范围
        float score = node.get("score").floatValue();
        if (score < 0 || score > 10) {
            throw new IllegalArgumentException("分数超出范围");
        }

        return node;
    }

    private ScoringResult buildScoringResult(JsonNode result) {
        String detailedComment = String.format(
                "知识点：%s | 语言：%s | 逻辑：%s",
                result.get("knowledge_comment").asText(),
                result.get("language_comment").asText(),
                result.get("logic_comment").asText()
        );

        return new ScoringResult(
                result.get("score").floatValue(),
                detailedComment,
                true
        );
    }

    private ScoringResult fallbackResult(ScoringRequest request) {
        // 可扩展为基于规则的兜底评分
        return new ScoringResult(
                0f,
                "系统评分失败，请人工复核",
                false
        );
    }

    // 辅助方法：从标准答案提取关键要点
    private String extractKeyPoints(String reference) {
        // 实现可根据业务需求定制
        return reference; // 简化示例
    }
}